/*****************************************************************************
 *  ENTROPY - emerging network to reduce orwellian potency yield
 *
 *  Copyright (C) 2002 Juergen Buchmueller <pullmoll@stop1984.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software Foundation,
 *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 *	$Id: shmalloc.h,v 1.9 2006/01/25 14:25:07 pullmoll Exp $
 *****************************************************************************/
#ifndef	_shmalloc_h_
#define	_shmalloc_h_

#include "osd.h"

#ifndef	SHM_DEBUG
#define	SHM_DEBUG 0
#endif

#undef	FILE_LINE_ARGS
#undef	FILE_LINE_PARMS
#if	SHM_DEBUG
#define	FILE_LINE_ARGS	,char *file, uint32_t line
#define	FILE_LINE_PARMS	,__FILE__, __LINE__
#define	AT_FILE_LINE at_file_line(file,line)
#else
#define	FILE_LINE_ARGS
#define	FILE_LINE_PARMS
#define	AT_FILE_LINE ""
#endif

#define	SHM_POOLSIZE (32*1024*1024)
#if	HAVE_MMAP == 0
#ifndef	SHMMAX
#define	SHMMAX		(4*1024*1024)
#endif
#else
#ifndef	SHMMAX
#define	SHMMAX		SHM_POOLSIZE
#endif
#endif
#define	SHM_POOLSEGS (SHM_POOLSIZE/SHMMAX)

typedef struct shm_pool_s {
#if	USE_SVID_SEMAPHORES || USE_FLOCK_SEMAPHORES
	osd_sem_global_t semglobals;
#endif
	osd_sem_t sem;
	size_t total;
	size_t alloc_len;
	size_t avail_len;
	void *allocated;
	void *available;
	size_t pool_cnt;				/* count of pools */
#if	HAVE_MMAP == 0
	int key[SHM_POOLSEGS];			/* shm key of pool */
	int shmid[SHM_POOLSEGS];		/* shmid of pool */
#endif
	size_t brk[SHM_POOLSEGS];		/* current brk per pool */
	size_t max[SHM_POOLSEGS];		/* max brk per pool */
	uint8_t *pool[SHM_POOLSEGS];	/* pool memory */
	uint8_t data[1];				/* for mmap(): flat mem */
}	shm_pool_t;

typedef struct shm_pool_stats_s {
	size_t total;					/* total amount of memory */
	size_t used;					/* used amount of memory */
	size_t free;					/* free amount of memory */
	size_t allocated;				/* number of nodes in the allocated list */
	size_t available;				/* number of nodes in the available list */
}	shm_pool_stats_t;

#ifdef	__cplusplus
extern "C" {
#endif
#if	HAVE_MMAP == 0
extern int g_shm_key;
extern int g_shm_id;
#endif
extern shm_pool_t *g_shm;

caddr_t shm_malloc(size_t size FILE_LINE_ARGS);
caddr_t shm_calloc(uint32_t num, size_t size FILE_LINE_ARGS);
caddr_t shm_realloc(caddr_t ptr, size_t size FILE_LINE_ARGS);
caddr_t shm_strdup(const char *src FILE_LINE_ARGS);
void shm_free(caddr_t ptr FILE_LINE_ARGS);
void shm_cfree(caddr_t ptr FILE_LINE_ARGS);
int shm_valid(caddr_t ptr FILE_LINE_ARGS);
int shm_pid_set(caddr_t ptr, pid_t pid FILE_LINE_ARGS);
int shm_pid_free(pid_t pid FILE_LINE_ARGS);
int shm_stats(shm_pool_stats_t *stats FILE_LINE_ARGS);

#define smalloc(size) shm_malloc(size FILE_LINE_PARMS)
#define scalloc(num,size) shm_calloc(num, size FILE_LINE_PARMS)
#define srealloc(ptr,size) shm_realloc((caddr_t)ptr, size FILE_LINE_PARMS)
#define sstrdup(src) shm_strdup(src FILE_LINE_PARMS)
#define sfree(ptr) shm_free((caddr_t)ptr FILE_LINE_PARMS)
#define scfree(ptr) shm_free((caddr_t)ptr FILE_LINE_PARMS)
#define svalid(ptr) shm_valid((caddr_t)ptr FILE_LINE_PARMS)
#define spset(ptr,pid) shm_pid_set((caddr_t)ptr, pid FILE_LINE_PARMS)
#define spfree(pid) shm_pid_free(pid FILE_LINE_PARMS)
#define	sstats(stats) shm_stats(stats FILE_LINE_PARMS)

void shm_pool_exit(void);
int shm_pool(char **argv);

#ifdef	__cplusplus
}
#endif

#endif	/* !defined(_shmalloc_h_) */
